package com.hzp.micromall.admin.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hzp.micromall.admin.dao.UmsResourceDao;
import com.hzp.micromall.admin.dao.UmsRoleDao;
import com.hzp.micromall.admin.dao.UmsRoleResourceRelationDao;
import com.hzp.micromall.admin.entity.UmsResource;
import com.hzp.micromall.admin.entity.UmsRole;
import com.hzp.micromall.admin.entity.UmsRoleResourceRelation;
import com.hzp.micromall.admin.service.UmsResourceService;
import com.hzp.micromall.common.core.api.CommonPage;
import com.hzp.micromall.common.core.constant.AuthConstant;
import com.hzp.micromall.common.core.constant.ServiceNameConstants;
import com.hzp.micromall.security.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author houzipeng
 * @Date 2022/2/24 23:09
 * @Version 1.0
 */
@Service
public class UmsResourceServiceImpl implements UmsResourceService {
    @Autowired
    private UmsResourceDao resourceDao;
    @Autowired
    private UmsRoleDao roleDao;
    @Autowired
    private UmsRoleResourceRelationDao roleResourceRelationDao;
    @Autowired
    private RedisService redisService;

    @Override
    public int createResource(UmsResource umsResource) {
        umsResource.setCreateTime(new Date());
        int count = resourceDao.insert(umsResource);
        initResourceRolesMap();
        return count;
    }

    @Override
    public int updateResourceById(Long id, UmsResource umsResource) {
        umsResource.setId(id);
        int count = resourceDao.updateById(umsResource);
        initResourceRolesMap();
        return count;
    }

    @Override
    public UmsResource getResourceDetail(Long id) {
        return resourceDao.selectById(id);
    }

    @Override
    public int deleteResourceById(Long id) {
        int count = resourceDao.deleteById(id);
        initResourceRolesMap();
        return count;
    }

    @Override
    public CommonPage<UmsResource> getResourcePageList(Long categoryId, String nameKeyword, String urlKeyword, Integer pageSize, Integer pageNum) {
        Page<UmsResource> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<UmsResource> wrapper = new LambdaQueryWrapper<>();
        if (categoryId != null) {
            wrapper.eq(UmsResource::getCategoryId, categoryId);
        }
        if (StrUtil.isNotEmpty(nameKeyword)) {
            wrapper.like(UmsResource::getName, nameKeyword);
        }
        if (StrUtil.isNotEmpty(urlKeyword)) {
            wrapper.like(UmsResource::getUrl, urlKeyword);
        }
        resourceDao.selectPage(page, wrapper);
        return new CommonPage<>(page.getCurrent(), page.getTotal(), page.getSize(), page.getRecords());
    }

    @Override
    public List<UmsResource> listAll() {
        return resourceDao.selectList(null);
    }

    @Override
    public Map<String, List<String>> initResourceRolesMap() {
        Map<String, List<String>> resourceRoleMap = new TreeMap<>();
        List<UmsResource> resourceList = resourceDao.selectList(null);
        List<UmsRole> roleList = roleDao.selectList(null);
        List<UmsRoleResourceRelation> relationList = roleResourceRelationDao.selectList(null);
        for (UmsResource resource : resourceList) {
            Set<Long> roleIds = relationList.stream().filter(item -> item.getResourceId().equals(resource.getId())).map(UmsRoleResourceRelation::getRoleId).collect(Collectors.toSet());
            List<String> roleNames = roleList.stream().filter(item -> roleIds.contains(item.getId())).map(item -> item.getId() + "_" + item.getName()).collect(Collectors.toList());
            resourceRoleMap.put("/" + ServiceNameConstants.getServiceUrlPrefix(resource.getCategoryId()) + resource.getUrl(), roleNames);
        }
        redisService.del(AuthConstant.RESOURCE_ROLES_MAP_KEY);
        redisService.hSetAll(AuthConstant.RESOURCE_ROLES_MAP_KEY, resourceRoleMap);
        return resourceRoleMap;
    }


}
